/*******************************************************************************
 *                                    ZLG
 *                         ----------------------------
 *                         innovating embedded platform
 *
 * Copyright (c) 2001-present Guangzhou ZHIYUAN Electronics Co., Ltd.
 * All rights reserved.
 *
 * Contact information:
 * web site:    https://www.zlg.cn
 *******************************************************************************/
#ifndef __HC32F4A0_TIMER_H
#define __HC32F4A0_TIMER_H

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus*/
#include "common/hc32f4a0_common.h"
#include "core/include/hc32f4a0_regs_timer.h"

/* \brief 定时器0 通道*/
#define TMR0_CH_A                       (0U)
#define TMR0_CH_B                       (1U)

/* \brief 定时器0 时钟分频*/
#define TMR0_CLK_DIV1                   (0UL << TMR0_BCONR_CKDIVA_POS)
#define TMR0_CLK_DIV2                   (1UL << TMR0_BCONR_CKDIVA_POS)
#define TMR0_CLK_DIV4                   (2UL << TMR0_BCONR_CKDIVA_POS)
#define TMR0_CLK_DIV8                   (3UL << TMR0_BCONR_CKDIVA_POS)
#define TMR0_CLK_DIV16                  (4UL << TMR0_BCONR_CKDIVA_POS)
#define TMR0_CLK_DIV32                  (5UL << TMR0_BCONR_CKDIVA_POS)
#define TMR0_CLK_DIV64                  (6UL << TMR0_BCONR_CKDIVA_POS)
#define TMR0_CLK_DIV128                 (7UL << TMR0_BCONR_CKDIVA_POS)
#define TMR0_CLK_DIV256                 (8UL << TMR0_BCONR_CKDIVA_POS)
#define TMR0_CLK_DIV512                 (9UL << TMR0_BCONR_CKDIVA_POS)
#define TMR0_CLK_DIV1024                (10UL << TMR0_BCONR_CKDIVA_POS)

/* \brief 定时器0 时钟源*/
#define TMR0_CLK_SRC_PCLK1              (0x00000000UL)
#define TMR0_CLK_SRC_INTHWTRIG          (TMR0_BCONR_SYNCLKA)
#define TMR0_CLK_SRC_LRC                (TMR0_BCONR_SYNSA)
#define TMR0_CLK_SRC_XTAL32             (TMR0_BCONR_ASYNCLKA | TMR0_BCONR_SYNSA)

/* \brief 定时器0 功能定义*/
#define TMR0_FUNC_CMP                   (0x00000000UL)
#define TMR0_FUNC_CAP                   (TMR0_BCONR_CAPMDA | TMR0_BCONR_HICPA)

/* \brief 定时器0 硬件触发功能定义*/
#define TMR0_BT_HWTRG_FUNC_START        (TMR0_BCONR_HSTAA)
#define TMR0_BT_HWTRG_FUNC_CLEAR        (TMR0_BCONR_HCLEA)
#define TMR0_BT_HWTRG_FUNC_STOP         (TMR0_BCONR_HSTPA)
#define TMR0_BT_HWTRG_FUNC_NONE         (0x00000000UL)
#define TMR0_BT_HETRG_FUNC_MASK         (TMR0_BT_HWTRG_FUNC_START | \
                                         TMR0_BT_HWTRG_FUNC_CLEAR | \
                                         TMR0_BT_HWTRG_FUNC_STOP)
#define TMR0_CHB_POS                    (16U)
#define TMR0_OFFEST(ch)                ((ch) * TMR0_CHB_POS)
#define TMR0_BCONR_INIT_MSK             (TMR0_BCONR_CAPMDA | TMR0_BCONR_CKDIVA | \
                                         TMR0_BCONR_HICPA  | TMR0_BCONR_HSTAA  | \
                                         TMR0_BCONR_HSTPA  | TMR0_BCONR_HCLEA)

#define TMR0_CHA_CLKSRC_MSK             (TMR0_BCONR_SYNSA  | TMR0_BCONR_SYNCLKA  | TMR0_BCONR_ASYNCLKA)

/* \brief 检查定时器0 是否合法*/
#define IS_VALID_TMR0(x)               (((x) == HC32F4A0_TMR0_1) || ((x) == HC32F4A0_TMR0_2))
/* \brief 检查定时器0 通道是否合法*/
#define IS_VALID_TMR0_CHANNEL(x)       (((x) == TMR0_CH_A) || ((x) == TMR0_CH_B))
/* \brief 检查定时器0 时钟分频是否合法*/
#define IS_VALID_TMR0_CLK_DIVISION(x)  (((x) == TMR0_CLK_DIV1)   || ((x) == TMR0_CLK_DIV2)   || \
                                        ((x) == TMR0_CLK_DIV4)   || ((x) == TMR0_CLK_DIV8)   || \
                                        ((x) == TMR0_CLK_DIV16)  || ((x) == TMR0_CLK_DIV32)  || \
                                        ((x) == TMR0_CLK_DIV64)  || ((x) == TMR0_CLK_DIV128) || \
                                        ((x) == TMR0_CLK_DIV256) || ((x) == TMR0_CLK_DIV512) || \
                                        ((x) == TMR0_CLK_DIV1024))
/* \brief 检查定时器0 时钟源是否合法*/
#define IS_VALID_TMR0_CLK_SRC(x)       (((x) == TMR0_CLK_SRC_PCLK1)  || ((x) == TMR0_CLK_SRC_INTHWTRIG) || \
                                        ((x) == TMR0_CLK_SRC_XTAL32) || ((x) == TMR0_CLK_SRC_LRC))
/* \brief 检查定时器0 功能是否合法*/
#define IS_VALID_TMR0_FUNC(x)          (((x) == TMR0_FUNC_CMP) || ((x) == TMR0_FUNC_CAP))
/* \brief 检查定时器0 硬件触发功能是否合法*/
#define IS_VALID_TMR0_HWTRG_FUNC(x)    (((x) | TMR0_BT_HETRG_FUNC_MASK) == TMR0_BT_HETRG_FUNC_MASK)

/* \brief 定时器 0 配置结构体 */
struct timr0_cfg {
    uint32_t clock_division;  /* 定时器 0 时钟分频 */
    uint32_t clock_source;    /* 定时器 0 时钟源 */
    uint32_t tmr0_func;       /* 定时器 0 功能 */
    uint32_t hw_trig_func;    /* 定时器 0 比对功能硬件触发功能 */
    uint16_t cmp_value;       /* 定时器 0 对比值（0 - 0xFFFF） */
    uint16_t cnt_value;       /* 定时器 0 计数值（0 - 0xFFFF） */
};

/**
 * \brief 定时器 0 初始化
 *
 * \param[in] p_tmr0_x 定时器 0 寄存器
 * \param[in] channel  定时器 0 通道
 * \param[in] p_cfg    定时器 0 配置
 *
 * \retval 成功返回 0
 */
int timer0_init(hc32f4a0_tmr0_regs_t *p_tmr0_x,
                uint8_t               channel,
                struct timr0_cfg     *p_cfg);
/**
 * \brief 定时器 0 反初始化
 *
 * \param[in] p_tmr0_x 定时器 0 寄存器
 */
void timer0_deinit(hc32f4a0_tmr0_regs_t *p_tmr0_x);
/**
 * \brief 定时器 0 启动
 *
 * \param[in] p_tmr0_x 定时器 0 寄存器
 * \param[in] channel  定时器 0 通道
 *
 * \retval 成功返回 0
 */
int timer0_start(hc32f4a0_tmr0_regs_t *p_tmr0_x,
                 uint8_t               channel);
/**
 * \brief 定时器 0 关闭
 *
 * \param[in] p_tmr0_x 定时器 0 寄存器
 * \param[in] channel  定时器 0 通道
 *
 * \retval 成功返回 0
 */
int timer0_stop(hc32f4a0_tmr0_regs_t *p_tmr0_x,
                uint8_t               channel);
/**
 * \brief 定时器 0 标志清除函数
 *
 * \param[in] p_tmr0_x 定时器 0 寄存器
 * \param[in] channel  定时器 0 通道
 *
 * \retval 成功返回 0
 */
int timer0_status_clr(hc32f4a0_tmr0_regs_t* p_tmr0_x, uint8_t channel);
/**
 * \brief 定时器 0 中断使能设置函数
 *
 * \param[in] p_tmr0_x  定时器 0 寄存器
 * \param[in] channel   定时器 0 通道
 * \param[in] is_enable 是否使能
 */
void timer0_int_enable_set(hc32f4a0_tmr0_regs_t *p_tmr0_x,
                           uint8_t               channel,
                           uint8_t               is_enable);
/**
 * \brief 定时器 0 触发源设置函数
 *
 * \param[in] event 事件
 */
void timer0_trigger_src_set(event_src_t event);
#ifdef __cplusplus
}
#endif  /* __cplusplus  */


#endif

